package com.atguigu.gmall.cart.service.impl;

import com.atguigu.gmall.cart.mapper.CartInfoMapper;
import com.atguigu.gmall.cart.service.CartInfoService;
import com.atguigu.gmall.cart.util.CartThreadLocalUtil;
import com.atguigu.gmall.common.cache.Java0409GmallCache;
import com.atguigu.gmall.common.constant.CartConst;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.product.feign.ProductFeign;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.util.concurrent.AtomicDouble;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * projectName: gmall
 *
 * @author: 陈鹏
 * time: 2022/10/7 15:45 星期五
 * description: 购物车新增操作接口类的实现类
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class CartInfoServiceImpl implements CartInfoService {

    @Autowired
    private ProductFeign productFeign;

    @Resource
    private CartInfoMapper cartInfoMapper;
    /**
     * 购物车新增操作
     *
     * @param skuId
     * @param num
     */
    @Override
    public void addCart(Long skuId, Integer num) {
        //参数校验
        if(skuId == null || num == null){
            throw new RuntimeException("参数错误");
        }
        //根据skuId查询商品
        SkuInfo skuInfo = productFeign.getSkuInfo(skuId);
        //校验是否有该商品
        if(skuInfo == null || skuInfo.getId() == null){
            throw new RuntimeException("商品不存在");
        }
        //判断用户的购物车是否已经有该商品,有则合并数量,没有则新增
        CartInfo cartInfo = cartInfoMapper.selectOne(new LambdaQueryWrapper<CartInfo>()
                .eq(CartInfo::getUserId, CartThreadLocalUtil.get())
                .eq(CartInfo::getSkuId, skuId));
        if(cartInfo == null || cartInfo.getId() == null){
            //将查询到的商品放入购物车
            cartInfo = new CartInfo();
            cartInfo.setUserId(CartThreadLocalUtil.get());
            cartInfo.setSkuId(skuId);
            //查询价格
            cartInfo.setCartPrice(productFeign.getPrice(skuId));
            //判断数量是否正确
            if(num <= 0){
                throw new RuntimeException("购物车数量不能小于等于零");
            }
            cartInfo.setSkuNum(num>200?199:num);
            cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
            cartInfo.setSkuName(skuInfo.getSkuName());
            //新增购物车数据
            int insert = cartInfoMapper.insert(cartInfo);
            if(insert <= 0){
                throw new RuntimeException("新增失败");
            }
        }else{
            num = cartInfo.getSkuNum() + num;
            if(num <= 0){
                //删除该用户购物车中该sku的数据
                cartInfoMapper.deleteById(cartInfo.getId());
            }else{
                //合并购物车数量---TODO--存在并发问题---乐观锁
                cartInfo.setSkuNum(num>200?199:num);
                //修改购物车表
                int update = cartInfoMapper.updateById(cartInfo);
                if(update < 0){
                    throw new RuntimeException("新增购物车失败");
                }
            }
        }
    }

    /**
     * 查询用户的购物车数据
     * @return
     */
    @Override
    //@Java0409GmallCache
    public List<CartInfo> getCartInfo() {
        return cartInfoMapper.selectList(new LambdaQueryWrapper<CartInfo>()
                .eq(CartInfo::getUserId,CartThreadLocalUtil.get()));
    }

    /**
     * 删除用户的购物车数据
     *
     * @param id
     */
    @Override
    public void removeCart(Long id) {
        int delete = cartInfoMapper.delete(new LambdaQueryWrapper<CartInfo>()
                .eq(CartInfo::getId, id)
                .eq(CartInfo::getUserId, CartThreadLocalUtil.get()));
        if(delete < 0){
            throw new RuntimeException("删除购物车数据失败");
        }
    }

    /**
     * 用户选中或取消选中单个或全部商品
     *
     * @param status
     * @param id
     */
    @Override
    public void checkOrUncheck(Short status, Long id) {
        //参数校验
        int result = 0;
        //全部或全不选
        if(id == null){
            result = cartInfoMapper.all(status,CartThreadLocalUtil.get());
        }else{
            //选中或不选单个
            result = cartInfoMapper.one(status,CartThreadLocalUtil.get(),id);
        }
        if(result < 0){
            return;
        }
    }

    /**
     * 合并用户购物车数据(用户登录前与用户登录后)
     *
     * @param cartInfoList
     */
    @Override
    public void mergeCart(List<CartInfo> cartInfoList) {
        cartInfoList.stream().forEach(cartInfo -> {
            this.addCart(cartInfo.getSkuId(),cartInfo.getSkuNum());
        });
    }

    /**
     * 查询订单页面用户选中的购物车数据
     *
     * @return
     */
    @Override
    public Map<String, Object> getCheckCart() {
        //返回结果初始化
        Map<String, Object> result = new HashMap<>();
        //查询
        List<CartInfo> cartInfoList = cartInfoMapper.selectList(new LambdaQueryWrapper<CartInfo>().
                eq(CartInfo::getUserId, CartThreadLocalUtil.get())
                .eq(CartInfo::getIsChecked, CartConst.CART_CHECKED));
        //判断
        if(cartInfoList == null || cartInfoList.isEmpty()){
            throw new RuntimeException("没有选中购物车数据,不允许下单!");
        }
        //计算总数量 计算总价格 线程安全类:AtomicInteger AtomicDouble
        AtomicInteger totalNum = new AtomicInteger();
        AtomicDouble totalMoney = new AtomicDouble();
        //为每个商品查询实时价格
        List<CartInfo> cartInfoListNew = cartInfoList.stream().map(cartInfo -> {
            //获取商品Id
            Long skuId = cartInfo.getSkuId();
            //查询实时价格
            BigDecimal price = productFeign.getPrice(skuId);
            //保存实时价格
            cartInfo.setSkuPrice(price);
            //获取当前这笔购物车的商品数量
            Integer skuNum = cartInfo.getSkuNum();
            //累加总数量
            totalNum.getAndAdd(skuNum);
            //累加总金额
            totalMoney.getAndAdd(price.doubleValue() * skuNum);
            //返回
            return cartInfo;
        }).collect(Collectors.toList());
        result.put("cartInfoList",cartInfoListNew);
        result.put("totalNum",totalNum);
        result.put("totalMoney",totalMoney);
        return result;
    }

    /**
     * 清除用户选中的购物车数据 时机-->订单生成成功后
     */
    @Override
    public void removeCheckCart() {
        int delete = cartInfoMapper.delete(new LambdaQueryWrapper<CartInfo>()
                .eq(CartInfo::getUserId, CartThreadLocalUtil.get())
                .eq(CartInfo::getIsChecked, CartConst.CART_CHECKED));
        if(delete < 0){
            throw new RuntimeException("清除购物车失败!!");
        }
    }
}
